using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using EventFlowLibrary;
using PerformanceUtility.GameDebugTools;
using ScreenManagement;

namespace FromTheSeaPt1
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class GameBase : Microsoft.Xna.Framework.Game
    {
        /// <summary>
        /// Graphics manager for the game.
        /// </summary>
        GraphicsDeviceManager graphics;

        /// <summary>
        /// Our debug system. We can keep this reference or use the DebugSystem.Instance property once we've called DebugSystem.Initialize.
        /// </summary>
        //DebugSystem debugSystem;

        /// <summary>
        /// Screenmanager for the game
        /// </summary>
        ScreenManager screenManager;

        /// <summary>
        /// Required to prevent double initialization.
        /// See: http://blog.nickgravelyn.com/2009/11/exception-handling-and-gamerservicescomponent/
        /// </summary>
        public static GamerServicesComponent GamerServices { get; private set; }

        /// <summary>
        /// By preloading any assets used by UI rendering, we avoid framerate glitches
        /// when they suddenly need to be loaded in the middle of a menu transition.
        /// </summary>
        static readonly string[] preloadAssets =
        {
            "Textures/Screens/gradient",
            "Textures/Screens/background",
            "Textures/Screens/logo",
            "Textures/Buttons/xboxControllerStart",
            "Music/Revealing_the_Truth",
            "Music/Nothing_Ever_Lasts",
            "Music/Revealing_the_Truth",
        };

        public GameBase()
        {
#if WINDOWS
            //System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("es-ES");
            //System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("ja-JP");
            System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US");
#endif

            graphics = new GraphicsDeviceManager(this);
            graphics.GraphicsProfile = GraphicsProfile.HiDef;
            graphics.PreferredBackBufferHeight = 720;
            graphics.PreferredBackBufferWidth = 1280;
            graphics.SynchronizeWithVerticalRetrace = true;
            graphics.IsFullScreen = false;
            Guide.SimulateTrialMode = false;
            IsFixedTimeStep = false;

            screenManager = new ScreenManager(this);
            Components.Add(screenManager);

            screenManager.AddScreen(new IntroScreen(), null);
            //screenManager.AddScreen(new BackgroundScreen(), PlayerIndex.One);
            //screenManager.AddScreen(new MainMenuScreen(), PlayerIndex.One);

            Content.RootDirectory = "Content";
        }

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // initialize the debug system with the game and the name of the font 
            // we want to use for the debugging
            //debugSystem = DebugSystem.Initialize(this, "Fonts/debugFont");
            //debugSystem.DebugCommandUI.DrawOrder = int.MaxValue;
            //debugSystem.DebugManager.DrawOrder = int.MaxValue;
            //debugSystem.FpsCounter.DrawOrder = int.MaxValue;
            //debugSystem.TimeRuler.DrawOrder = int.MaxValue;
            //debugSystem.EventDisplayer.DrawOrder = int.MaxValue;

            // register a new command that lets us exit
            //debugSystem.DebugCommandUI.RegisterCommand(
            //    "exit",                 // Name of command
            //    "exit application",     // Description of command
            //    ExitCommand);
            //debugSystem.DebugCommandUI.RegisterCommand(
            //    "quit",                 // Name of command
            //    "exit application",     // Description of command
            //    ExitCommand);

#if XBOX

#endif
            GamerServices = new GamerServicesComponent(this);
            Components.Add(GamerServices);

            base.Initialize();



            // Initialize after base.Initialize()
            //GamerServices.Initialize();
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            foreach (string asset in preloadAssets)
            {
                Content.Load<object>(asset);
            }
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            base.UnloadContent();
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            // Tell the TimeRuler that we're starting a new frame. you always want
            // to call this at the start of Update. Start measuring time for "Update".
            //debugSystem.TimeRuler.StartFrame();
            //debugSystem.TimeRuler.BeginMark("Update", Color.Blue);

            base.Update(gameTime);
            
            // Stop measuring time for "Update".
            //debugSystem.TimeRuler.EndMark("Update");
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            // Start measuring time for "Draw".
            //debugSystem.TimeRuler.BeginMark("Draw", Color.Yellow);

            GraphicsDevice.Clear(Color.Black);

            base.Draw(gameTime);

            // Stop measuring time for "Draw".
            //debugSystem.TimeRuler.EndMark("Draw");
        }

        /// <summary>
        /// This method is called from DebugCommandHost when the user types the 'exit'
        /// command into the command prompt. This is registered with the command prompt
        /// through the DebugCommandUI.RegisterCommand method we called in Initialize.
        /// </summary>
        private void ExitCommand(IDebugCommandHost host, string command, IList<string> arguments)
        {
            this.Exit();
        }
    }
}
